package server

import (
	apiV1 "SmartLibrary/api/v1"
	"SmartLibrary/docs"
	"SmartLibrary/internal/handler"
	"SmartLibrary/internal/middleware"
	"SmartLibrary/pkg/jwt"
	"SmartLibrary/pkg/log"
	"SmartLibrary/pkg/server/http"
	"SmartLibrary/pkg/snowflake"
	"github.com/gin-gonic/gin"
	"github.com/spf13/viper"
	swaggerFiles "github.com/swaggo/files"
	ginSwagger "github.com/swaggo/gin-swagger"
	"time"
)

func NewHTTPServer(
	logger *log.Logger,
	conf *viper.Viper,
	jwt *jwt.JWT,
	snowflake *snowflake.Sf,
	userHandler *handler.UserHandler,
	adminHandler *handler.AdminHandler,
	bookAdminHandler *handler.BookAdminHandler,
) *http.Server {
	gin.SetMode(gin.DebugMode)
	s := http.NewServer(
		gin.Default(),
		logger,
		http.WithServerHost(conf.GetString("http.host")),
		http.WithServerPort(conf.GetInt("http.port")),
	)

	// swagger doc
	docs.SwaggerInfo.BasePath = "/v1"
	s.GET("/swagger/*any", ginSwagger.WrapHandler(
		swaggerFiles.Handler,
		//ginSwagger.URL(fmt.Sprintf("http://localhost:%d/swagger/doc.json", conf.GetInt("app.http.port"))),
		ginSwagger.DefaultModelsExpandDepth(-1),
		ginSwagger.PersistAuthorization(true),
	))

	s.Use(
		middleware.GenerateRequestID(logger, snowflake),
		middleware.CORSMiddleware(),
		middleware.ResponseLogMiddleware(logger),
		middleware.RequestLogMiddleware(logger),
		//middleware.SignMiddleware(log), // 签名中间件 如若使用需要配置相关密钥
	)
	s.GET("/ping", func(ctx *gin.Context) {
		logger.WithContext(ctx).Info("hello")
		apiV1.HandleSuccess(ctx, map[string]interface{}{
			"＜（＾－＾）＞": "Thank you for using SmartLibrary!",
		})
	})

	v1 := s.Group("/v1")
	{
		// No route group has permission
		noAuthRouter := v1.Group("/")
		{
			noAuthRouter.POST("/user/login", userHandler.Login)
			noAuthRouter.POST("/bookAdmin/login", bookAdminHandler.LoginBookAdmin)
			noAuthRouter.POST("/admin/login", adminHandler.Login) //系统管理员登录

			noAuthRouter.GET("/user/books", userHandler.GetBooks)
			noAuthRouter.GET("/user/rules", userHandler.GetRules)
			noAuthRouter.GET("/user/notices", userHandler.GetNotices)
			noAuthRouter.GET("/user/comments", userHandler.GetComments)

			noAuthRouter.POST("/admin/register", adminHandler.AddAdmin) //注册系统管理员

		}

		// Non-strict permission routing group
		noStrictAuthRouter := v1.Group("/").Use(middleware.NoStrictAuth(jwt, logger))

		{
			noStrictAuthRouter.GET("/bookAdmin/get_data", bookAdminHandler.GetBookAdmin)
			noStrictAuthRouter.GET("/bookAdmin/query_expire", bookAdminHandler.OverdueBookAdmin)
			noStrictAuthRouter.GET("/bookAdmin/query_book", bookAdminHandler.BookReturnBookAdmin)
			noStrictAuthRouter.GET("/bookAdmin/get_borrow_statement", bookAdminHandler.BorrowReportBookAdmin)
			noStrictAuthRouter.GET("/bookAdmin/get_return_statement", bookAdminHandler.ReturnReportBookAdmin)
			noStrictAuthRouter.GET("/bookAdmin/get_notice_list", bookAdminHandler.GetNoticeBookAdmin)
			noStrictAuthRouter.GET("/bookAdmin/get_notice", bookAdminHandler.GetNoticeIdBookAdmin)

			noStrictAuthRouter.GET("/user", userHandler.GetProfile)
			noStrictAuthRouter.GET("/user/borrows", userHandler.GetBorrows)
			noStrictAuthRouter.GET("/user/violations", userHandler.GetViolations)
		}
		// Strict permission routing group
		strictAuthRouter := v1.Group("/").Use(middleware.StrictAuth(jwt, logger))
		{
			strictAuthRouter.POST("/bookAdmin/borrow_book", bookAdminHandler.BookBorrowBookAdmin)
			strictAuthRouter.POST("/bookAdmin/return_book", bookAdminHandler.ReturnBookAdmin)
			strictAuthRouter.POST("/bookAdmin/add_notice", bookAdminHandler.AddNoticeBookAdmin)
			strictAuthRouter.POST("/bookAdmin/delete_notice", bookAdminHandler.DeleteNoticeBookAdmin)
			strictAuthRouter.POST("/bookAdmin/update_notice", bookAdminHandler.UpdateNoticeBookAdmin)
			strictAuthRouter.POST("/user/comments", userHandler.CreateComment)

			//1.6.1 书籍管理
			strictAuthRouter.GET("/admin/bookLists", adminHandler.GetBookLists)         //获取图书列表
			strictAuthRouter.GET("/admin/simpleBookTypeList", adminHandler.GetBookType) //获取图书分类
			strictAuthRouter.POST("/admin/books", adminHandler.AddBooks)                //添加图书
			strictAuthRouter.DELETE("/admin/books", adminHandler.DeleteBooks)           //删除图书
			strictAuthRouter.DELETE("/admin/allBooks", adminHandler.DeleteAllBooks)     //删除所有图书
			strictAuthRouter.PUT("/admin/books", adminHandler.PutBookInformation)       //修改图书信息
			strictAuthRouter.GET("/admin/books", adminHandler.GetBookInformation)       //获取图书信息

			//1.6.2 书籍类型
			strictAuthRouter.GET("/admin/bookTypeList", adminHandler.GetBookTypeList)    //获取图书分类列表
			strictAuthRouter.POST("/admin/bookType", adminHandler.AddBookTypes)          //添加图书分类
			strictAuthRouter.DELETE("/admin/bookType", adminHandler.DeleteBookType)      //删除图书分类
			strictAuthRouter.PUT("/admin/bookType", adminHandler.PutBookTypeInformation) //修改图书分类信息
			strictAuthRouter.GET("/admin/bookType", adminHandler.GetBookTypeInformation) //获取图书分类信息
			//1.6.3 借阅证管理
			strictAuthRouter.GET("/admin/libraryCardsList", adminHandler.GetLibraryCardsList)             //获取借阅证列表
			strictAuthRouter.POST("/admin/libraryCards", adminHandler.AddLibraryCard)                     //添加借阅证
			strictAuthRouter.DELETE("/admin/libraryCards", adminHandler.DeleteLibraryCard)                //删除借阅证
			strictAuthRouter.PUT("/admin/libraryCards", adminHandler.PutLibraryCardInformation)           //修改借阅证
			strictAuthRouter.PUT("/admin/libraryCardsRuleNumber", adminHandler.PutLibraryCardInformation) //修改借阅证的借阅规则
			strictAuthRouter.GET("/admin/libraryCards", adminHandler.LibraryCardInformation)              //获取借阅证
			//1.6.4借阅信息查询
			strictAuthRouter.GET("/admin/borrowsList", adminHandler.GetBorrowsList) //获取借阅信息
			//1.6.5借阅规则管理
			strictAuthRouter.GET("/admin/borrowRulesList", adminHandler.GetBorrowRulesList)       //获取借阅规则列表
			strictAuthRouter.GET("/admin/borrowAllRulesList", adminHandler.GetBorrowAllRulesList) //Simple获取借阅规则列表
			strictAuthRouter.POST("/admin/borrowRules", adminHandler.AddBorrowRules)              //添加借阅规则
			strictAuthRouter.DELETE("/admin/borrowRules", adminHandler.DeleteBorrowRules)         //删除借阅规则
			strictAuthRouter.PUT("/admin/borrowRules", adminHandler.PutBorrowRules)               //修改借阅规则
			strictAuthRouter.GET("/admin/borrowRules", adminHandler.GetBorrowRules)               //获取借阅规则

			//1.6.6图书管理员管理
			strictAuthRouter.GET("/admin/bookAdminList", adminHandler.GetBookAdminList) //获取图书管理员列表
			strictAuthRouter.POST("/admin/bookAdmin", adminHandler.AddBookAdmin)        //添加图书管理员
			strictAuthRouter.DELETE("/admin/bookAdmin", adminHandler.DeleteBookAdmin)   //删除图书管理员
			strictAuthRouter.PUT("/admin/bookAdmin", adminHandler.PutBookAdmin)         //修改图书管理员
			strictAuthRouter.GET("/admin/bookAdmin", adminHandler.GetBookAdmin)         //获取图书管理员

			//1.6.7 系统管理
			strictAuthRouter.GET("/admin/borrowData", adminHandler.GetBorrowData)         //获取最近28天借阅数据
			strictAuthRouter.GET("/admin/borrowTypeData", adminHandler.GetBorrowTypeData) //获取所有的借书分类统计

		}
		// Websocket permission routing group
		wsAuthRouter := v1.Group("/").Use(middleware.WebsocketAuth(jwt, logger), middleware.RateLimit(logger, 1, time.Second))
		{
			wsAuthRouter.GET("/user/chats", userHandler.GetChats)
		}
	}

	return s
}
